/*
 * Vec2.cpp.inl
 *
 *  Created on: 19.09.2009
 *      Author: christoph
 */

// this file is included by its header file to satisfy the compiler

namespace mehari {
namespace common {

template < typename Real >
Vec2<Real>::Vec2() {
	data[0] = 0;
	data[1] = 0;
}

template < typename Real >
Vec2<Real>::Vec2( const Real x, const Real y ) {
	data[0] = x;
	data[1] = y;
}

template <typename Real>
Vec2<Real>::Vec2( const Vec2<Real>& v ) {
	data[0] = v.x();
	data[1] = v.y();
}

template <typename Real>
Vec2<Real>::~Vec2() {
}

template <typename Real>
Real Vec2<Real>::x() const {
	return data[0];
}

template <typename Real>
Real& Vec2<Real>::x() {
	return data[0];
}

template <typename Real>
Real Vec2<Real>::y() const {
	return data[1];
}

template <typename Real>
Real& Vec2<Real>::y() {
	return data[1];
}

template <typename Real>
const Real Vec2<Real>::operator [] ( int iIndex ) const {
	return data[iIndex];
}

template <typename Real>
Real Vec2<Real>::operator [] ( int iIndex ) {
	return data[iIndex];
}

template <typename Real>
Vec2<Real> Vec2<Real>::operator + ( const Vec2<Real>& vRhs ) const {
	return Vec2<Real>( data[0] + vRhs.data[0], data[1] + vRhs.data[1] );
}

template <typename Real>
Vec2<Real> Vec2<Real>::operator - ( const Vec2<Real>& vRhs ) const {
	return Vec2<Real>( data[0] - vRhs.data[0], data[1] - vRhs.data[1] );
}

template <typename Real>
Vec2<Real> Vec2<Real>::operator * ( const Real rRhs ) const {
	return Vec2<Real>( data[0] * rRhs, data[1] * rRhs );
}

template <typename Real>
Vec2<Real> Vec2<Real>::operator / ( const Real rRhs ) const {
	return Vec2<Real>( data[0] / rRhs, data[1] / rRhs );
}

template <typename Real>
Vec2<Real> Vec2<Real>::operator - () const {
	return Vec2<Real>( -data[0], -data[1] );
}

template <typename Real>
Vec2<Real> Vec2<Real>::operator += ( const Vec2<Real>& vRhs ) {
	data[0] += vRhs.data[0];
	data[1] += vRhs.data[1];
}

template <typename Real>
Vec2<Real> Vec2<Real>::operator -= ( const Vec2<Real>& vRhs ) {
	data[0] -= vRhs.data[0];
	data[1] -= vRhs.data[1];
}

template <typename Real>
Vec2<Real> Vec2<Real>::operator *= ( const Real rRhs ) {
	data[0] *= rRhs;
	data[1] *= rRhs;
}

template <typename Real>
Vec2<Real> Vec2<Real>::operator /= ( const Real rRhs ) {
	data[0] /= rRhs;
	data[1] /= rRhs;
}

// TODO comparison operations
template <typename Real>
bool Vec2<Real>::operator == ( const Vec2<Real>& v2Rhs ) const {
	return 		this->data[0] == v2Rhs.data[0]
	       &&	this->data[1] == v2Rhs.data[1];
}

template <typename Real>
bool Vec2<Real>::operator != ( const Vec2<Real>& v2Rhs ) const {
	return 		this->data[0] != v2Rhs.data[0]
	       &&	this->data[1] != v2Rhs.data[1];
}

template <typename Real>
Real Vec2<Real>::length() const {
	return Math<Real>::Sqrt( data[0] * data[0] + data[1] * data[1] );
}

template <typename Real>
Real Vec2<Real>::squaredLength() const {
	return data[0] * data[0] + data[1] * data[1];
}

template <typename Real>
Real Vec2<Real>::normalize() {
	Real length = this->length();
	data[0] /= length;
	data[1] /= length;
	return length;
}

template <typename Real>
Real Vec2<Real>::dot( const Vec2& v2A ) const {
	return this->data[0] * v2A.data[0] + this->data[1] * v2A.data[1];
}

// vec2 specific
template <typename Real>
Vec2<Real> Vec2<Real>::perp() const {
	return Vec2<Real>( data[1], -data[2] );
}

template <typename Real>
Vec2<Real> Vec2<Real>::unitPerp() const {
	Vec2<Real> result( data[1], -data[2] );
	result.normalize();
	return result;
}

template <typename Real>
Real Vec2<Real>::dotPerp( const Vec2<Real>& v2Val ) const {
	// TODO implement me
}

template <typename Real>
void Vec2<Real>::orthonormalize( Vec2<Real>& v2U, Vec2<Real>& v2V ) {
	// TODO implement me
}

template <typename Real>
void Vec2<Real>::generateOrthonormalBasis( Vec2<Real>& v2U, Vec2<Real>& v2V, bool bUnitLengthV ) {
	// TODO implement me
}



} // namespace common
} // namespace mehari
